#include <stdio.h>
#include "src/cpp/generic.h"
#include "src/collection/array.h"

#include "src/collection/loop_queue.h"
#include <stdlib.h>

void test();

int main() {
    test();
    exit(0);
}

void print_lq(const struct LoopQueue *lq) {
    struct Array *array = loop_queue_to_array(lq);

    printf("arr : size : %lu\n", array->size);
    printf("[");
    for (usize i = 0; i < array->size; ++i) {
        usize *u = array_get(array, i);
        printf(" %lu ", *u);
    }
    printf("]\n");
    free_array(array);
}

void test() {
    int a = 1;
    int b = 5;
    printf("before cpp_swap a = %d, b = %d\n", a, b);
    cpp_swap(&a, &b, sizeof(int));
    printf("after cpp_swap a = %d, b = %d\n", a, b);
    struct T {
        int i;
        double d;
    };
    size_t ts = sizeof(struct T);
    struct T *pt = malloc(ts);
    pt->i = 1;
    pt->d = 3.14;
    struct Array *data = cpp_transfer_data(pt, ts);
    printf("T size is %lu arr size : %lu\n", ts, data->size);
    struct T *t = (struct T *) cpp_transfer_back(data);
    printf("t : i = %d, d = %f\n", t->i, t->d);

    free(pt);
    free(t);
    free_array(data);

    struct LoopQueue *lq = new_loop_queue(sizeof(usize), 2);
    usize *u1 = malloc(sizeof(usize));
    *u1 = 1;
    usize *u2 = malloc(sizeof(usize));
    *u2 = 2;
    usize *u3 = malloc(sizeof(usize));
    *u3 = 3;
    usize *u4 = malloc(sizeof(usize));
    *u4 = 4;
    loop_queue_push(lq, u1);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);
    loop_queue_push(lq, u2);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);

    printf(" 1 : %lu , 2 : %lu \n", *(usize *) (lq->start - lq->type_size), *(usize *) lq->start);

    loop_queue_push(lq, u3);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);
    loop_queue_push(lq, u4);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);

    free(u1);
    free(u2);
    free(u3);
    free(u4);
    u1 = loop_queue_pop_first(lq);
    u2 = loop_queue_pop_first(lq);
    u3 = loop_queue_pop_first(lq);
    u4 = loop_queue_pop_first(lq);
    printf("u1 = %lu , u2 = %lu , u3 = %lu , u4 = %lu\n", *u1, *u2, *u3, *u4);

    loop_queue_push(lq, u1);
    free(u1);
    u1 = loop_queue_pop_first(lq);
    loop_queue_push(lq, u1);
    free(u1);
    u1 = loop_queue_pop_first(lq);
    loop_queue_push(lq, u1);
    free(u1);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);
    loop_queue_push(lq, u2);
    free(u2);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);
    loop_queue_push(lq, u3);
    free(u3);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);
    loop_queue_push(lq, u4);
    free(u4);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);

    loop_queue_expansion(lq);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);

    usize *u5 = malloc(sizeof(usize));
    *u5 = 5;
    loop_queue_push(lq, u5);
    free(u5);
    printf("%s\n", loop_queue_to_json(lq));
    print_lq(lq);

    u1 = loop_queue_pop_first(lq);
    u2 = loop_queue_pop_first(lq);
    u3 = loop_queue_pop_first(lq);
    u4 = loop_queue_pop_first(lq);
    u5 = loop_queue_pop_first(lq);
    printf("u1 = %lu , u2 = %lu , u3 = %lu , u4 = %lu , u5 = %lu\n", *u1, *u2, *u3, *u4, *u5);


    free_loop_queue(lq);
}
